﻿//#define TRACKING
#define VERBOSE
//#define SIMPLIFY

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mathematics;
using Mathematics.Parser;

namespace MathConsole
{
    class Program
    {
        private const string HEADER =
@"
********************************************************************************
*                                                                              *
*                         MATH CONSOLE v.0.1                                   *
*                                                                              *
*                                 by                                           *
*                             Zane Thorn                                       *
*                                                                              *
*                           Copyright 2010                                     *
*                                                                              *
********************************************************************************";


        static void Main(string[] args)
        {
            Console.Write(HEADER);
            Console.WriteLine();
           

            string line;
            do
            {
                var domain = Domain.CurrentDomain;
                for (int i = 1; i <= domain.Depth; i++)
                    Console.Write(".");
                Console.Write(":>");
                line = Console.ReadLine();
                if (string.IsNullOrWhiteSpace(line))
                    continue;

            } while (Commands.EvaluateCommands(line)); 

        }

        static void Process(string input)
        {
            // Preprocess any console commands



            //try
            //{
#if TRACKING
            var start = DateTime.Now;
#endif
                var tokenExpression = Lexersize(input);
                var mathExpression = Parse(tokenExpression);
#if SIMPLIFY
            mathExpression = Simplify(mathExpression);
#endif
                Evaluate(mathExpression);

#if TRACKING
            var end = DateTime.Now;
            var span = end - start;
            Console.WriteLine();
            Console.WriteLine("Total Time: {0}ms", span.TotalMilliseconds);
#endif
            //}
            //catch (Exception ex)
            //{
            //    Console.ForegroundColor = ConsoleColor.Red;
            //    Console.WriteLine(ex.Message);
            //    Console.ForegroundColor = ConsoleColor.White;
            //}
        }

        static TokenString Lexersize(string input)
        {
#if TRACKING
            var start = DateTime.Now;
#endif

            var expression = Lexer.LexLine(input);
#if VERBOSE
            Console.WriteLine();
#if TRACKING
            var end = DateTime.Now;
            var span = end - start;
            Console.WriteLine("Total Lexing Time: {0}ms", span.TotalMilliseconds);
#endif
            Console.WriteLine("Lexical Output:");
            foreach (var token in expression)
            {
                Console.WriteLine(token);
            }
#endif
            return expression;
        }

        static MathExpression Parse(TokenString tokens)
        {
#if TRACKING
            var start = DateTime.Now;
#endif

            var expression = MathParser.ParseExpression(tokens);
#if VERBOSE
            Console.WriteLine();
#if TRACKING
            var end = DateTime.Now;
            var span = end - start;
            Console.WriteLine("Total Parsing Time: {0}ms", span.TotalMilliseconds);
#endif
            Console.WriteLine("Parser Output:");
            Console.WriteLine(expression.ToString());
#endif
            return expression;
        }

        static MathExpression Simplify(MathExpression complex)
        {
#if TRACKING
            var start = DateTime.Now;
#endif
            var simple = complex.Simplify();
#if VERBOSE
            Console.WriteLine();
#if TRACKING
            var end = DateTime.Now;
            var span = end - start;
            Console.WriteLine("Total Simplify Time: {0}ms", span.TotalMilliseconds);
#endif
            Console.WriteLine("Simplifyer Output:");
            Console.WriteLine(simple.ToString());
#endif
            return simple;
        }

        static void Evaluate(MathExpression expression)
        {
            if (expression.CanEvaluate())
            {
                Console.WriteLine();
#if TRACKING
                var start = DateTime.Now;
#endif

                var result = expression.Evaluate();

#if TRACKING
                var end = DateTime.Now;
                var span = end - start;
                Console.WriteLine("Total Evaluation Time: {0}ms", span.TotalMilliseconds);
#endif
                Console.WriteLine("Evaluation Result:");
                Console.WriteLine(result);
            }
            else
            {
                Console.WriteLine();
                Console.WriteLine("Expression cannot be evaluated.");
            }
        }
    }
}
